﻿using SpyApp.Models;
using SpyApp.Models.BaseCommon;
using SpyApp.Models.BaseCommon.Enum;
using SpyApp.Models.BaseCommon.ERROR_CODE;
using SpyApp.Models.BaseCommon.MSG_STR;
using SpyApp.Models.EntytiRepossitory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace SpyApp.Controllers
{
    public class AccountController : Controller
    {
        string _messageError = "";


        public UserRepository userRepository { get; set; }

        public AccountController()
        {
            this.userRepository = new UserRepository();
        }

        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            //Nghia: Nếu đã đăng nhập chuyển đến Home
            if (Request.IsAuthenticated)
            {
                return RedirectToAction("Index", "Home");
            }
            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Login(AccountModel.LoginModel model, string returnUrl)
        {
            //Nghĩa: Check Validate
            if (ModelState.IsValid)
            {
                //Tan: Kiểm tra user login
                User user = new Models.User();
                SpyApp.Models.BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT errCode = this.userRepository.Login(model.Email, model.Password, ref _messageError, ref user);
                //Tân: Đăng nhập thành công    
                if (errCode == Models.BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS)
                {
                    //NGhia: catch UserName, Session, về returnUrl nếu có, nếu không về Home
                    _messageError = AUTH_MESSAGE_STRING.LOGIN_SUCCESSFUL;
                    Session["User"] = user;
                    FormsAuthentication.SetAuthCookie(user.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                            && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    return RedirectToAction("Index", "Home");
                }
                else if (errCode == Models.BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.DO_NOT_EXIST)
                {
                    _messageError = AUTH_MESSAGE_STRING.WRONG_PASSWORD;
                }
            }

            ModelState.AddModelError("", _messageError);
            return View(model);
        }


        public ActionResult Logoff()
        {
            //Nghia: xóa catch, đến trang Login
            Session.Abandon();
            Session.Clear();
            FormsAuthentication.SignOut();
            return View("Logoff");
        }


        [AllowAnonymous]
        public ActionResult Register(AccountModel.RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                //Nghia: validate
                if (Session["captcha"] == null || Session["captcha"].ToString() != model.Captcha)
                {
                    _messageError = AUTH_MESSAGE_STRING.WRONG_CAPTCHA;
                }
                else
                {
                    //User user = this.this.userRepository.AddNewAccount(model, ref _messageError);
                    User user = new User();
                    var errCode = this.userRepository.AddNewAccount(model, ref _messageError, ref user);
                    if (errCode == Models.BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.SUCCESS)
                    {
                        // gởi mail
                        string subject = "Confirmation of Registration";
                        string domainPath = string.Format("{0}{1}", Request.Url.GetLeftPart(UriPartial.Authority), Url.Content("~")); // lấy tên domain
                        string link = domainPath + Url.Action("Active", "Account", new { active_code = user.ActiveInvationCode }).Remove(0,1); // bỏ / đầu tiên
                        List<EmailUtils.KEYWORD> keys = new List<EmailUtils.KEYWORD>()
                        {
                            new EmailUtils.KEYWORD() {Key = "KEY_APP_NAME", Value="Safe App"},
                            new EmailUtils.KEYWORD() {Key = "KEY_APP_LINK_CONFIRM", Value=link},
                        };
                        string emailTemplateFileName = Server.MapPath("~/EmailTemplate/EmailActiveTemplate.html");
                        string body = EmailUtils.MakeEmailBody(emailTemplateFileName, keys);
                        //string body = "Please activate your account by going to the followin URL: \n";
                        //body += "http://localhost:11326/api/user/" + user.ActiveInvationCode.ToString();

                        if (this.userRepository.SendMail(subject, body, user.UserName.ToString(), true, true) != "Send email successful!")
                        {
                            _messageError = AUTH_MESSAGE_STRING.SENDMAIL_ERROR;
                        }
                        // Chuyển đến trang đăng nhập thành công
                        TempData["register-success-username"] = model.Email;
                        return RedirectToAction("RegisterSuccess", "Account");
                    }
                }
            }
            ModelState.AddModelError("", _messageError);
            return View();
        }


        [AllowAnonymous]
        public ActionResult RegisterSuccess()
        {
            ViewBag.RegisterSuccessUsername = TempData["register-success-username"];
            return View();
        }
        

        [AllowAnonymous]
        public ActionResult Active(string active_code)
        {
            if (string.IsNullOrEmpty(active_code))
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            // active user
            SpyApp.Models.User user = new Models.User();
            ERROR_CODE_USER_VERIFY errCode = this.userRepository.VerifyUser(active_code, ref _messageError, ref user);
            if (errCode == ERROR_CODE_USER_VERIFY.SUCCESS)
            {
                // update lại user status
                user.UserStatus = DBEntity.UserStatus.Active;
                ERROR_CODE_ITEMS_UPDATE errCodeUpdate = this.userRepository.Update(user.Id, user, ref _messageError);
                if (errCodeUpdate == ERROR_CODE_ITEMS_UPDATE.SUCCESS)
                {
                    TempData["active-success-username"] = user.UserName;
                    return RedirectToAction("ActiveSuccess", "Account");
                }
            }
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        [AllowAnonymous]
        public ActionResult ActiveSuccess()
        {
            ViewBag.ActiveSuccessUsername = TempData["active-success-username"];
            return View();
        }


        public ActionResult ChangePassword(AccountModel.ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                string username = System.Web.HttpContext.Current.User.Identity.Name;
                //ERROR_CODE_ITEMS_UPDATE errCode = this.userRepository.ChangePassword(username, model.OldPassword, model.NewPassword, ref _messageError);
                ERROR_CODE_ITEMS_UPDATE errCode = ERROR_CODE_ITEMS_UPDATE.SYSTEM_ERROR;
                _messageError = "lỗi gì gì đó";
                if (errCode == ERROR_CODE_ITEMS_UPDATE.SUCCESS)
                {
                    TempData["MessageSuccess"] = "Change password success";
                    return RedirectToAction("Index", "Home");
                }
            }
            ModelState.AddModelError("", _messageError);
            return View();
        }

        [AllowAnonymous]
        public ActionResult ForgotPassword(string username)
        {
            if (!string.IsNullOrEmpty(username))
            {
                if (ModelState.IsValid)
                {
                    User user = new User();
                    userRepository.GetByUserName(username, ref _messageError, ref user);
                    if (user != null)
                    {
                        // make active code
                        user.ActiveInvationCode = userRepository.CreateActivationCode(username);
                        ERROR_CODE_ITEMS_UPDATE errCode = userRepository.Update(user.Id, user, ref _messageError);
                        if (errCode == ERROR_CODE_ITEMS_UPDATE.SUCCESS)
                        {
                            // send forgotpassword mail
                            string subject = "Reset password link";
                            string domainPath = string.Format("{0}{1}", Request.Url.GetLeftPart(UriPartial.Authority), Url.Content("~")); // lấy tên domain
                            string link = domainPath + Url.Action("ResetPassword", "Account", new { reset_code = user.ActiveInvationCode }).Remove(0, 1); // bỏ / đầu tiên
                            List<EmailUtils.KEYWORD> keys = new List<EmailUtils.KEYWORD>()
                        {
                            new EmailUtils.KEYWORD() {Key = "KEY_APP_NAME", Value="Safe App"},
                            new EmailUtils.KEYWORD() {Key = "KEY_APP_LINK_CONFIRM", Value=link},
                        };
                            string emailTemplateFileName = Server.MapPath("~/EmailTemplate/EmailResetPasswordTemplate.html");
                            string body = EmailUtils.MakeEmailBody(emailTemplateFileName, keys);
                            //string body = "Please activate your account by going to the followin URL: \n";
                            //body += "http://localhost:11326/api/user/" + user.ActiveInvationCode.ToString();

                            if (this.userRepository.SendMail(subject, body, user.UserName.ToString(), true, true) != "Send email successful!")
                            {
                                _messageError = AUTH_MESSAGE_STRING.SENDMAIL_ERROR;
                            }
                            // Chuyển đến trang gởi mail thành công
                            TempData["forgotpassword-success-username"] = username;
                            return RedirectToAction("ForgotPasswordSuccess", "Account");
                        }

                        // reciver mail => change password
                    }
                    _messageError = "User name not exist.";
                }
            }
            ModelState.AddModelError("", _messageError);
            return View();
        }

        [AllowAnonymous]
        public ActionResult ForgotPasswordSuccess()
        {
            ViewBag.Username = TempData["forgotpassword-success-username"];
            return View();
        }


        [AllowAnonymous]
        public ActionResult ResetPassword(string reset_code, Models.AccountModel.ChangePasswordModel model)
        {
            if (string.IsNullOrEmpty(reset_code))
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            // active user
            SpyApp.Models.User user = new Models.User();
            ERROR_CODE_USER_VERIFY errCode = this.userRepository.VerifyUser(reset_code, ref _messageError, ref user);
            if (errCode == ERROR_CODE_USER_VERIFY.SUCCESS)
            {
                // update lại user password
                //ERROR_CODE_ITEMS_UPDATE errCodeUpdate = this.userRepository.ResetPassword(model.NewPassword, ref _messageError);
                ERROR_CODE_ITEMS_UPDATE errCodeUpdate = ERROR_CODE_ITEMS_UPDATE.SYSTEM_ERROR;
                _messageError = "lỗi gì gì đó";
                if (errCodeUpdate == ERROR_CODE_ITEMS_UPDATE.SUCCESS)
                {
                    TempData["MessageSuccess"] = "Change password success";
                    return RedirectToAction("Index", "Home");
                }
                ModelState.AddModelError("", _messageError);
                return View();
            }
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }


        [Authorize]
        [ChildActionOnly]
        public ActionResult AccountInfoPartial()
        {
            string username = System.Web.HttpContext.Current.User.Identity.Name;
            User user = new Models.User();
            var errCode = this.userRepository.GetByUserName(username, ref _messageError, ref user);
            return PartialView(user);
        }


    }
}
